<template>
  <div class="mapbox-maps">
    <div id="map"></div>
    <div class="btns">
      <input
        type="button"
        class="btn btn0"
        :value="isRotate ? '停止旋转' : '开启旋转'"
      />
      <input
        type="button"
        class="btn btn1"
        :value="isShowName ? '隐藏名字标注' : '显示名字标注'"
      />
      <select class="sel-map" @change="selValue()">
        <option v-for="(it, i) in mapSty" :value="it" :key="i" class="sel-item">
          {{ it }}
        </option>
      </select>
    </div>
  </div>
</template>

<script>
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import MapboxLanguage from '@mapbox/mapbox-gl-language'
// import CitySelectorControl from 'city-selector-control'
// import 'city-selector-control/style.css'
export default {
  data: () => ({
    map: null,
    // 夜色样式 / 街景样式 / 高亮模式 / 户外模式 / 卫星模式
    mapSty: ['dark-v10', 'streets-v11', 'light-v10', 'outdoors-v11', 'satellite-v9'],
    isRotate: true, // 到达初始化定位点是否旋转
    isShowName: true, // 是否显名字标注
    selIndex: 0, // 只有地图的是夜色模式的时候才可以进行3D模型的显示
    pointArr: []
  }),
  methods: {
    selValue () {
      let sel0 = document.querySelector('.sel-map')
      this.selIndex = sel0.selectedIndex
      let sel0Value = sel0.options[this.selIndex].value
      this.map.setStyle('mapbox://styles/mapbox/' + sel0Value);
      console.log(sel0Value)
    },
    // 按钮事件绑定
    onBtnEvent () {
      let btns = document.querySelectorAll('.btn')
      btns.forEach((it, i) => {
        if (i === 0) { // 
          it.addEventListener('click', () => {
            this.isRotate = !this.isRotate
          })
        }
        // else if (i === 1) {
        // 	it.addEventListener('click', () => {
        // 		if (this.isShowName) {
        // 			this.hideLayers('points')
        // 			this.isShowName = !this.isShowName
        // 		} else {
        // 			this.showLayers('points')
        // 			this.isShowName = !this.isShowName
        // 		}
        // 	})
        // }
      })
    },
    // camera旋转函数
    rotateCamera (timestamp, isRotate) {
      if (this.isRotate) {
        this.map.rotateTo((timestamp / 100) % 360, {
          duration: 0
        });
        requestAnimationFrame(this.rotateCamera);
      }
    },
    // 获取点的点位数据
    getPointDate () {
      this.$http.get('./assets/json/points.json').then(res => {
        console.log('点位的json数据', res.data)
        this.pointArr = res.data
        this.loadPoint(res.data)
      })
    },
    // 获取线的点位数据
    getLineDate () {
      this.$http.get('./assets/json/line0.json').then(res => {
        console.log('线的点位数据', res.data)
        this.loadLine(res.data)
      })
    },
    // 获取区域的点位数据
    getPolygeoDate () {
      this.$http.get('./assets/json/ss.json').then(res => {
        console.log('区域点位数据', res.data)
        this.loadArea(res.data)
      })
    },
    // 3Dbuilding形式加载地图
    load3DBuilding () {
      // 3D效果显示地图
      this.map.on('load', () => {
        // this.rotateCamera(0);
        // Insert the layer beneath any symbol layer.
        var layers = this.map.getStyle().layers;

        var labelLayerId;
        for (var i = 0; i < layers.length; i++) {
          if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
            labelLayerId = layers[i].id;
            break;
          }
        }
        this.map.addLayer({
          'id': '3d-buildings',
          'source': 'composite',
          'source-layer': 'building',
          'filter': ['==', 'extrude', 'true'],
          'type': 'fill-extrusion',
          'minzoom': 15,
          'paint': {
            // 'fill-extrusion-color': '#aaa',
            'fill-extrusion-color': [
              "interpolate",
              ["exponential", 0.99],
              ["get", "height"],
              0,
              "#23ffff",
              500,
              "#3df687"
            ],

            // use an 'interpolate' expression to add a smooth transition effect to the
            // buildings as the user zooms in
            'fill-extrusion-height': [
              "interpolate", ["linear"],
              ["zoom"],
              15, 0,
              15.05, ["get", "height"]
            ],
            'fill-extrusion-base': [
              "interpolate", ["linear"],
              ["zoom"],
              15, 0,
              15.05, ["get", "min_height"]
            ],
            'fill-extrusion-opacity': .5
          }
        }, labelLayerId);
      });
    },
    // 地图样式改变
    changeMapStyle () {
      // 路的标签的颜色设置
      this.map.on('load', () => {
        this.map.setPaintProperty("land", 'background-color', '#1e3533')
        // "landcover"
        this.map.setPaintProperty('landuse', 'fill-color', '#5d5e41')
        // road-path
        this.map.setPaintProperty("water", 'fill-color', '#18ecff')
        // road-street
        this.map.setPaintProperty('road-street', 'line-color', '#c5ff8f')
        this.map.setPaintProperty('road-label', 'text-color', '#07ff98')
        // water-point-label
        this.map.setPaintProperty('water-point-label', 'text-color', '#03ff0b')
        // settlement-label
        this.map.setPaintProperty('poi-label', 'text-color', '#ddff00')
      })
    },
    // 监听改变建筑颜色事件
    changeBUildingColor () {
      // building背景色
      this.map.on('click', (e) => {
        let features = this.map.queryRenderedFeatures(e.point, {
          layers: ['3d-buildings']
        })
        console.log(features, 'fffff')
        if (features.length > 0) {
          this.map.setPaintProperty('3d-buildings', 'fill-extrusion-color', '#77fe92')
        } else {
          this.map.setPaintProperty('3d-buildings', "fill-extrusion-color", '#ff59e1')
        }
        // this.map.setPaintProperty('3d-buildings', 'fill-extrusion-color', '#6e0007');
        console.log(this.map.getStyle().layers)
      })
    },
    // 点击显示被点击的点位并飞行
    cameraFlyTo () {
      // 显示点击的点位
      this.map.on('click', e => {
        console.log(e)
        if (e.lngLat) {
          this.map.flyTo({
            center: [e.lngLat.lng, e.lngLat.lat],
            zoom: 18,
            curve: 3,
            pitch: 45, //目标俯仰角
            bearing: -17.5, //目标方位角
            speed: 0.1, //飞行速度
            duration: 3000, //飞行总时长，单位ms
            essential: true, //动画
          })
        }
        let features = this.map.queryRenderedFeatures(e.point)
        console.log(features[0], 'sss')
        // if (features.length && features[0].layer.id === 'points') {
        // 	this.hideLayers(features[0].layer.id)
        // 	this.isShowName = !this.isShowName
        // }
        if (Object.prototype.toString.call(features) === '[object Object]' && features[0]
          .hasOwnProperty('properties') && features[0].properties.name) {
          console.log(features[0].properties.name)
        }
      })
    },
    // 地图汉语语言设置
    setChinese () {
      // 设置语言
      var language = new MapboxLanguage({
        defaultLanguage: "zh-Hans"
      });
      this.map.addControl(language);
    },
    // 加载点
    loadPoint (list) {
      var map = this.map;
      map.on("load", function () {
        map.loadImage("./assets/images/map.png", function (error, image) {
          if (error) throw error;
          map.addImage("map", image);
          map.addSource("point", {
            type: "geojson",
            data: list,
          });
          map.addLayer({
            id: "points",
            type: "symbol",
            source: "point", // reference the data source
            layout: {
              "icon-image": "map", // reference the image
              "icon-size": 0.5,
              "icon-allow-overlap": true, //点位避让效果，一定程度上可代替聚合,true表示开启，不会造成重合
            },
          });
        });
      });
    },
    // 加载线
    loadLine (list) {
      let map = this.map;
      // let _this = this
      map.on("load", function () {
        map.addSource("lineSource", {
          type: "geojson",
          data: list,
        });
        map.addLayer({
          id: "line",
          type: "line",
          source: "lineSource",
          layout: {},
          paint: {
            "line-color": "#ff0693",
            "line-width": 3,
          },
        });
      });
    },
    // 加载面
    loadArea (list) {
      let map = this.map;
      // let _this = this
      map.on("load", function () {
        map.addSource("citySource", {
          type: "geojson",
          data: list,
        });
        map.addLayer({
          id: "city",
          type: "fill",
          source: "citySource",
          layout: {},
          paint: {
            "fill-color": "#fa61ff", // blue color fill
            "fill-opacity": 0.2,
          },
        });
      });
    },
    // 删除图层
    removeLayers (name) {
      if (this.map.getLayer(name)) {
        this.map.removeLayer(name)
      }
    },
    // 删除数据源
    removeSources (name) {
      if (this.map.getSource(name)) {
        this.map.removeSource(name)
      }
    },
    // 隐藏图层
    hideLayers (name) {
      if (this.map.getLayer(name)) {
        this.map.setLayoutProperty(name, 'visibility', 'none')
      }
    },
    // 显示图层
    showLayers (name) {
      if (this.map.getLayer(name)) {
        this.map.setLayoutProperty(name, 'visibility', 'visible')
      }
    },
    // popup
    loadPopup () {
      this.map.on('click', 'points', (e) => {
        console.log(e, '-----------')
        this.hideLayers('points')  // 先隐藏图层
        let popup = new mapboxgl.Popup()
          .setLngLat(e.lngLat)
          .setHTML(` <div class="hover-popup" >
						<div style="font-size:14px; color:#333;background: transparent">                    
              <div style="margin-top:5px"><span style="color:#999;">ID：${e.features[0].id}</span><span>35个</span></div>
              <div style="margin-top:5px"><span style="color:#999;">信息：</span><span>1个</span></div>
            </div>
          </div>
        `)
          .addTo(this.map);
        popup.on('close', e => {
          console.log('监听弹窗关闭')
          this.map.flyTo({
            center: [117.25360822524635, 31.86324137091252],
            zoom: 15,
            curve: 3,
            pitch: 45, //目标俯仰角
            bearing: -17.5, //目标方位角
            speed: 0.1, //飞行速度
            duration: 3000, //飞行总时长，单位ms
            essential: true, //动画
          })
          console.log(this.pointArr, 'ssssss')
          this.loadPoint(this.pointArr)
          // 再显示图层
          this.showLayers('points')
        })
        popup.on('open', function (e) {
          alert('监听弹窗打开')
        })
      });
    },
    // 初始化地图
    initMap () {
      let _this = this
      this.map = new mapboxgl.Map({
        accessToken: 'pk.eyJ1IjoiMTAxOTA2OTAwNSIsImEiOiJjanc1dHhqemUxYzloNDZwY3p4OHVhdmxqIn0.PFZ3RGgKNVy7UIwiwdTT_g',
        container: 'map',
        style: `mapbox://styles/mapbox/${this.mapSty[0]}`,
        center: [117.38565857435873, 31.93999443845557],
        zoom: 5,
        antialias: false,
        attributionControl: false,
        pitch: 60, // pitch in degrees
        bearing: -60, // bearing in degrees
      })
      // 城市选择
      // 自定义配置项
      // const citySelectorOptions = {
      //   theme: 'light',
      //   placeholder: '全国',
      //   hot: ['110000', '340500'],
      //   zoom: 10
      // };
      // this.map.addControl(new CitySelectorControl(citySelectorOptions), 'top-right');
      // 导航控制条
      var nav = new mapboxgl.NavigationControl();
      this.map.addControl(nav, 'bottom-right');
      this.map.flyTo({
        center: [117.25360822524635, 31.86324137091252],
        zoom: 14,
        curve: 3,
        pitch: 45, //目标俯仰角
        bearing: -17.5, //目标方位角
        speed: 0.1, //飞行速度
        duration: 4000, //飞行总时长，单位ms
        essential: true, //动画
      })



      // 初始化点是否旋转
      setTimeout(() => {
        if (this.isRotate) {
          this.rotateCamera(0)
        }
      }, 10000)

    }
  },
  mounted () {
    this.initMap()
    this.getPointDate()
    this.getPolygeoDate()
    this.getLineDate()
    // 3d加载building  => 夜色模式显示3D建筑
    if (this.selIndex === 0) {
      this.load3DBuilding()
      // 地图样式改变
      this.changeMapStyle()
    }
    // 建筑颜色改变事件监听
    this.changeBUildingColor()
    // 点击显示被点击的点位并飞行
    this.cameraFlyTo()
    // 地图设置中文
    this.setChinese()
    // 按钮事件绑定
    this.onBtnEvent()
    // 改变图形样式 
    // this.selValue()
    this.loadPopup()
  }
}
</script>

<style lang="scss">
.mapbox-maps {
  width: 100%;
  height: calc(100vh - 50px);
  position: relative;

  #map {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;

    .mapboxgl-canvas {
      outline: none;
    }

    // 隐藏mapbox商标
    .mapboxgl-ctrl-logo {
      display: none;
    }
  }

  .btns {
    width: 600px;
    height: 60px;
    // border: 1px solid red;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);

    .btn {
      width: 120px;
      height: 40px;
      background-color: rgba(0, 0, 0, 0);
      border: 1px dashed #d2269e;
      border-radius: 5px;
      color: #02ffef;
      font-size: 16px;
      font-weight: 500;
    }

    .btn:hover {
      border: 1px dashed #01d2af;
      color: #eaff00;
      font-size: 16px;
      font-weight: 500;
    }
  }
}
</style>
